package com.aboverock.module.system.service.impl;

import static org.springframework.ldap.query.LdapQueryBuilder.query;

import java.util.List;

import javax.naming.NamingException;
import javax.naming.directory.Attributes;

import org.apache.shiro.authc.AuthenticationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.query.LdapQuery;
import org.springframework.stereotype.Service;

import com.aboverock.common.enums.UserSexEnum;
import com.aboverock.common.enums.UserStatusEnum;
import com.aboverock.module.system.domain.User;
import com.aboverock.module.system.service.LdapService;

/**
 * The Class LdapServiceImpl.
 *
 * @author Rock Wang
 */
@Service
public class LdapServiceImpl implements LdapService {
    private static Logger logger = LoggerFactory.getLogger(LdapServiceImpl.class);

    @Autowired
    private LdapTemplate ldapTemplate;

    /** 查询用户属性定义. */
    public static final String[] USER_ATTRIBUTES = new String[] { "cn", "physicalDeliveryOfficeName", "description",
        "mobile", "ipPhone", "distinguishedName", "department", "mail", "extensionAttribute5" };

    @Override
    public List<User> searchLdapUsers(String loginName) {
        LdapQuery query = query().attributes(USER_ATTRIBUTES).where("objectclass").is("user").and("cn").is(loginName);
        return ldapTemplate.search(query, new UserMapper());
    }

    @Override
    public List<User> fuzzySearchLdapUsers(String loginName) {
        LdapQuery query = query().attributes(USER_ATTRIBUTES).where("objectclass").is("user").and("cn").like(loginName);
        return ldapTemplate.search(query, new UserMapper());
    }

    @Override
    public boolean authenticate(String loginName, String credentials) {
        try {
            ldapTemplate.authenticate(query().where("cn").is(loginName), credentials);
        } catch (Exception e) {
            logger.error(e.getLocalizedMessage(), e);
            throw new AuthenticationException(e);
        }
        return true;
    }

    private static class UserMapper implements AttributesMapper<User> {

        @Override
        public User mapFromAttributes(Attributes attributes) throws NamingException {
            User user = new User();
            user.setLoginName(getStringAttribute(attributes, "cn"));
            user.setName(getStringAttribute(attributes, "description"));
            user.setAddress(getStringAttribute(attributes, "physicalDeliveryOfficeName"));
            user.setStatus(UserStatusEnum.NORMAL.getValue());

            String sex = getStringAttribute(attributes, "extensionAttribute5");
            user.setSex(UserSexEnum.getSexEnum(sex).getValue());

            user.setMobilephone(getStringAttribute(attributes, "mobile"));
            user.setTel(getStringAttribute(attributes, "ipPhone"));
            user.setDept(getStringAttribute(attributes, "department"));
            user.setEmail(getStringAttribute(attributes, "mail"));

            return user;
        }

        private String getStringAttribute(Attributes attributes, String attributeName) throws NamingException {
            return (String) attributes.get(attributeName).get();
        }
    }
}
